package cn.com.huzo.webapp.controller.inventory;

import cn.com.huzo.model.entities.inventory.StockInHeaderEntity;
import cn.com.huzo.model.entities.inventory.StockInLinesEntity;
import cn.com.huzo.model.entities.inventory.StockInLinesPoLinesEntity;
import cn.com.huzo.model.entities.master.StockReasonEntity;
import cn.com.huzo.service.inventory.StockInHeaderManager;
import cn.com.huzo.service.inventory.StockInLinesManager;
import cn.com.huzo.service.inventory.StockInLinesPoHeaderManager;
import cn.com.huzo.service.inventory.StockInLinesPoLinesManager;
import cn.com.huzo.service.master.StockReasonManager;
import cn.com.huzo.service.purchase.PoLinesManager;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import huzofw.common.web.controller.BaseFormController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 入库单画面控制器
 *
 * @author 吴旭
 */
@Controller
@RequestMapping(value = "/inventory/stock_in")
public class StockInController extends BaseFormController {

    // <editor-fold defaultstate="collapsed" desc="属性">
    @Resource(name = "StockInHeaderManager")
    private StockInHeaderManager _manager_header;

    @Resource(name = "StockInLinesPoHeaderManager")
    private StockInLinesPoHeaderManager _manager_lines_poheader;

    @Resource(name = "StockInLinesPoLinesManager")
    private StockInLinesPoLinesManager _manager_lines_polines;

    @Resource(name = "StockInLinesManager")
    private StockInLinesManager _manager_lines;

    @Resource(name = "StockReasonManager")
    private StockReasonManager _manager_stock_reason;

    @Resource(name = "PoLinesManager")
    private PoLinesManager _manager_po_lines;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="画面处理部分">
    /**
     * 跳转到入库单一览画面
     * <p>
     * @param request
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping("/list.html")
    public ModelAndView redirectListWnd(HttpServletRequest request) throws Exception {
        ModelAndView view = new ModelAndView();
        view.setViewName("inventory.stock_in.list.def");
        return view;
    }

    /**
     * 跳转入库单编辑画面
     * <p>
     * @param request 上下文请求
     * @param action 操作类别 1：增加 2：编辑
     * @param stockInId 入库单ID
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping("/{action}/{stockInId}/edit.html")
    public ModelAndView redirectEditWnd(HttpServletRequest request, @PathVariable(value = "action") int action,
            @PathVariable(value = "stockInId") Long stockInId) throws Exception {
        ModelAndView view = new ModelAndView();
        // 得到入出库原因
        List<StockReasonEntity> stockReasonList = _manager_stock_reason.fetchAll(1);
        view.addObject("StockReasonList", stockReasonList);
        view.addObject("action", action);
        view.addObject("stockInId", stockInId);
        view.setViewName("inventory.stock_in.edit.def");
        return view;
    }

    /**
     * 入库单选择画面
     * <p>
     * @param request
     * @return
     * @throws java.lang.Exception
     */
    @RequestMapping("/choice.html")
    public ModelAndView redirectChoice(HttpServletRequest request) throws Exception {
        ModelAndView view = new ModelAndView();
        view.setViewName("popup.inventory.stock_in.choice.def");
        return view;
    }

    /**
     * 入库单-打印预览画面
     * <p>
     * @return
     */
    @RequestMapping("/print.html")
    public ModelAndView redirectPrintPreviewWnd() {
        ModelAndView view = new ModelAndView();
        view.setViewName("print.inventory.material_stock_in.print.def");
        return view;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="主表-数据处理部分">
    /**
     * 得到新的单据号
     * <p>
     * @return @throws Exception
     */
    @RequestMapping(value = "/header/fetchNewNoOfBill.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchNewBillNo() throws Exception {
        Map<String, Object> _result = new HashMap();
        _result.put("BillNo", _manager_header.fetchNewBillNo());
        return _result;
    }

    /**
     * 根据标识取得入库单数据。
     *
     * @param criterion 入库单标识
     * @return 入库单数据（包括主表和子表）。
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/header/fetchByKey.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchByHeaderKey(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_header.fetchByHeaderKey(
                MapUtils.getLong(criterion, "HeaderId"),
                MapUtils.getLong(criterion, "CurrentUserId"),
                MapUtils.getLong(criterion, "WorkFlowId"),
                MapUtils.getInteger(criterion, "LimitPoLines"),
                MapUtils.getInteger(criterion, "Limit"));
    }

    /**
     * 根据条件取得入库单信息分页数据。
     * <p>
     * @param criterion 检索条件
     * @return 入库单信息分页数据
     * @throws Exception
     */
    @RequestMapping(value = "/header/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchForPage(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_header.fetchForPage(criterion);
    }

    /**
     * 保存入库单信息数据。
     * <p>
     * @param instance 要保存的入库单信息对象。
     * @return 新增记录主键.
     * @throws Exception
     */
    @RequestMapping(value = "/header/save.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Long save(@RequestBody final StockInHeaderEntity instance) throws Exception {
        Long rowsAffected;

        if (instance.getHeaderId() > 0) { // 编辑
            rowsAffected = (long) _manager_header.update(instance);
        } else {                          // 新增
            rowsAffected = _manager_header.insert(instance);
        }

        return rowsAffected;
    }

    /**
     * 删除入库单信息数据。
     *
     * @param criterion 要删除的数据。
     * @return 删除后的数据。
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/header/delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> delete(@RequestBody final Map<String, Object> criterion) throws Exception {
        return _manager_header.delete(criterion);
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="明细-引入采购订单数据处理部分">
    /**
     * 通过引入采购订单，新增入库单明细信息数据。
     * <p>
     * @param criterion 引用的采购订单、各个明细显示的记录数
     * @return 引入的采购订单主表、明以及入库单明细.
     * @throws Exception
     */
    @RequestMapping(value = "/lines/poheader/insert.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> importFromPo(@RequestBody Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<Long> poHeaderIdList = mapper.convertValue(MapUtils.getObject(criterion, "PoHeaderIdList"), new TypeReference<List<Long>>() {
        });

        List<String> poLinesIdList;
        if (MapUtils.getInteger(criterion, "SelectAllFlag") == 1) {
            poLinesIdList = _manager_po_lines.fetchAllSelectedLines(criterion);
        } else {
            poLinesIdList = mapper.convertValue(MapUtils.getObject(criterion, "PoLinesIdList"), new TypeReference<List<String>>() {
            });
        }

        return _manager_lines_poheader.insert(
                MapUtils.getLong(criterion, "HeaderId"),
                poHeaderIdList, poLinesIdList,
                MapUtils.getInteger(criterion, "Limit02"),
                MapUtils.getInteger(criterion, "Limit03"),
                MapUtils.getLong(criterion, "UserId"));
    }

    /**
     * 根据条件取得引入的采购订单明细分页数据。
     * <p>
     * @param criterion 检索条件
     * @return 引入的采购订单主表、明以及入库单明细
     * @throws Exception
     */
    @RequestMapping(value = "/lines/polines/FetchLinesForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchLinePoLines(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_lines_polines.fetchForPage(criterion);
    }

    /**
     * 更新到货明细
     * <p>
     * @param criterion 引用的采购订单、各个明细显示的记录数
     * @return 引入的采购订单明细以及入库单明细.
     * @throws Exception
     */
    @RequestMapping(value = "/lines/polines/update.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> updateLinesPooLines(@RequestBody Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<StockInLinesPoLinesEntity> itemList = mapper.convertValue(MapUtils.getObject(criterion, "ItemList"), new TypeReference<List<StockInLinesPoLinesEntity>>() {
        });

        Map<String, Object> _result = new HashMap();
        if (!itemList.isEmpty()) {
            _result = _manager_lines_polines.update(itemList,
                    MapUtils.getInteger(criterion, "Limit02"),
                    MapUtils.getInteger(criterion, "PageIndex02"));
        }
        return _result;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="入库单明细数据处理部分">
    /**
     * 根据条件取得引入的采购订单明细分页数据。
     * <p>
     * @param criterion 检索条件
     * @return 引入的采购订单主表、明以及入库单明细
     * @throws Exception
     */
    @RequestMapping(value = "/lines/fetchForPage.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> fetchLineForPage(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_lines.fetchForPage(criterion);
    }

    /**
     * 删除入库单明细数据。
     *
     * @param criterion 要删除的入库单、各个明细显示的记录数
     * @return 引入的采购订单主表、明以及入库单明细。
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/lines/delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> deleteLines(@RequestBody Map<String, Object> criterion) throws Exception {
        return _manager_lines.delete(
                MapUtils.getLong(criterion, "HeaderId"),
                MapUtils.getString(criterion, "LinesId"),
                MapUtils.getInteger(criterion, "Limit02"),
                MapUtils.getInteger(criterion, "PageIndex02"),
                MapUtils.getInteger(criterion, "Limit03"),
                MapUtils.getInteger(criterion, "PageIndex03"));
    }

    /**
     * 批量删除明细信息数据。
     *
     * @param criterion 批量删除的数据以及当前分页情况数据
     * @return 删除后的订单明细及相关引入数据。
     * @throws java.lang.Exception
     */
    @RequestMapping(value = "/lines/batch_delete.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> batchDeleteLines(@RequestBody final Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<StockInLinesEntity> _deletedLinesList = mapper.convertValue(MapUtils.getObject(criterion, "DeletedLinesList"), new TypeReference<List<StockInLinesEntity>>() {
        });

        if (_deletedLinesList.isEmpty()) {
            Map<String, Object> _result = new HashMap();
            _result.put("Success", false);
            return _result;
        } else {
            return _manager_lines.batchDeleteLines(
                    MapUtils.getLong(criterion, "HeaderId"),
                    MapUtils.getLong(criterion, "DeletedBy"),
                    MapUtils.getInteger(criterion, "Limit02"),
                    MapUtils.getInteger(criterion, "PageIndex02"),
                    MapUtils.getInteger(criterion, "Limit03"),
                    MapUtils.getInteger(criterion, "PageIndex03"),
                    _deletedLinesList);
        }
    }

    /**
     * 更新入库单明细
     * <p>
     * @param criterion 要更新的数据、各个明细显示的记录数
     * @return 引入的采购订单明细以及入库单明细
     * @throws Exception
     */
    @RequestMapping(value = "/lines/update.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> updateLines(@RequestBody Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<StockInLinesEntity> itemList = mapper.convertValue(MapUtils.getObject(criterion, "ItemList"), new TypeReference<List<StockInLinesEntity>>() {
        });

        Map<String, Object> _result = new HashMap();
        if (!itemList.isEmpty()) {
            _result = _manager_lines.update(itemList,
                    MapUtils.getInteger(criterion, "Limit02"),
                    MapUtils.getInteger(criterion, "PageIndex02"),
                    MapUtils.getInteger(criterion, "Limit03"),
                    MapUtils.getInteger(criterion, "PageIndex03"));
        }

        return _result;
    }

    /**
     * 清空入库单明细的到货允许
     * <p>
     * @param criterion 要更新的数据、各个明细显示的记录数
     * @return 引入的采购订单明细以及入库单明细
     * @throws Exception
     */
    @RequestMapping(value = "/lines/clearArrivalAllowed.html",
            method = RequestMethod.POST)
    public @ResponseBody
    Map<String, Object> clearArrivalAllowed(@RequestBody Map<String, Object> criterion) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        List<StockInLinesEntity> itemList = mapper.convertValue(MapUtils.getObject(criterion, "ItemList"), new TypeReference<List<StockInLinesEntity>>() {
        });

        Map<String, Object> _result = new HashMap();
        if (!itemList.isEmpty()) {
            _result = _manager_lines.clearArrivalAllowed(itemList,
                    MapUtils.getInteger(criterion, "Limit02"),
                    MapUtils.getInteger(criterion, "PageIndex02"),
                    MapUtils.getInteger(criterion, "Limit03"),
                    MapUtils.getInteger(criterion, "PageIndex03"));
        }

        return _result;
    }
    // </editor-fold>
}
